package com.alogic.uid.impl;

import com.alogic.uid.IdGenerator;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.Script;
import com.alogic.xscript.doc.XsObject;
import com.alogic.xscript.doc.json.JsonObject;
import com.anysoft.util.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.w3c.dom.Element;
import java.util.HashMap;

/**
 * 通过脚本来预分配
 *
 * @since 1.6.13.5 [20200605 duanyy]
 */
public class FromScript extends IdGenerator.Prepare {
    /**
     * 客户端
     */
    protected String client = "unknown";

    /**
     * 序列id
     */
    protected String id = "default";

    /**
     * 分配序列号的事件
     */
    protected Logiclet onPreprare = null;

    @Override
    public void configure(Properties p) {
        client = PropertiesConstants.getString(p,"client",client);
        id = PropertiesConstants.getString(p, "id", id);
        super.configure(p);
    }

    @Override
    public void configure(Element e, Properties p) {
        Properties props = new XmlElementProperties(e,p);

        Element onPreprareElem = XmlTools.getFirstElementByPath(e, "on-prepare");
        if (onPreprareElem != null){
            onPreprare = Script.create(onPreprareElem, props);
        }

        configure(props);
    }

    @Override
    public void onPrepare(long current, long capacity) {
        if (onPreprare == null){
            LOG.warn("event onPrepare is not found, return 0");
            doPrepare(current, Long.MAX_VALUE);
            return;
        }
        LogicletContext logicletContext = new LogicletContext(Settings.get());
        try {
            logicletContext.SetValue("$current",String.valueOf(current));
            logicletContext.SetValue("$capacity",String.valueOf(capacity));
            logicletContext.SetValue("$id",id);
            logicletContext.SetValue("$client",client);
            XsObject doc = new JsonObject("root", new HashMap<String, Object>());
            onPreprare.execute(doc, doc, logicletContext, null);
            long newCurrent = PropertiesConstants.getLong(logicletContext,"$current",current);
            long newCapacity = PropertiesConstants.getLong(logicletContext,"$capacity",capacity);
            doPrepare(newCurrent,newCapacity);
        } catch (Exception ex) {
            LOG.info("Failed to execute onload script" + ExceptionUtils.getStackTrace(ex));
            doPrepare(current,Long.MAX_VALUE);
        }
    }
}
